﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyBasicLib.Reflection;
using MyBasicLib.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.IO;
namespace MyBasicLib.Utilities
{
    public class IOC
    {
        /// <remarks>
        /// 现在一个应用程序里同一个接口只能使用同一个实现 ,并且配置的修改要重启应用才能生效
        /// </remarks> 
        public static readonly IContainer DefaultContainer;
        static IOC()
        {
            DefaultContainer = new Container();
            Startup.InitIOC();
        }
        public static IContainer GetContainer(string containerName)
        {
            return new Container();
        }
    }
    public interface IContainer
    {
        void Register<T>(Func<T> func) where T : class;
        void Register<T>(Func<T> func, bool isSingleton) where T : class;
        T Resolve<T>() where T : class;
    }

    //public sealed class ConfigContainer : IContainer
    //{
    //    private IList<ObjectElement> objectElementList;
    //    public ConfigContainer()
    //    {
    //        if (null != Config.Instence)
    //            this.objectElementList = Config.Instence.ObjectElementList;
    //        if (null == this.objectElementList)
    //            this.objectElementList = new List<ObjectElement>();
    //    }
    //    static readonly object oLock = new object();
    //    static readonly object rLock = new object();

    //    public void Register<T>(Func<T> func) where T : class
    //    {
    //        Register<T>(func, false);
    //    }
    //    public void Register<T>(Func<T> func, bool isSingleton) where T : class
    //    {
    //        if (isSingleton)
    //            SingletonObjectCache<T>.Instence = func();
    //        FuncCache<T>.Instence = func;
    //    }

    //    public T Resolve<T>() where T : class
    //    {
    //        if (SingletonObjectCache<T>.Instence != null)
    //            return SingletonObjectCache<T>.Instence;

    //        if (!IsRegistered<T>())
    //        {
    //            if (ObjectInitInfoCache<T>.Instence == null)
    //            {
    //                lock (oLock)
    //                {
    //                    if (ObjectInitInfoCache<T>.Instence == null)
    //                    {
    //                        var objElement = objectElementList.SingleOrDefault(p => p.ServiceType == typeof(T));

    //                        ObjectInitInfoCache<T>.Instence = objElement.ToInitInfo();
    //                    }
    //                }
    //            }
    //            lock (rLock)
    //            {
    //                if (!IsRegistered<T>())
    //                {
    //                    Register<T>(ObjectInitInfoCache<T>.Instence.ToObject<T>, ObjectInitInfoCache<T>.Instence.Singleton);
    //                }
    //            }
    //        }
    //        if (SingletonObjectCache<T>.Instence != null)
    //            return SingletonObjectCache<T>.Instence;

    //        if (!IsRegistered<T>())
    //        {
    //            throw new BasicLibException("该对象尚未注册过.");
    //        }

    //        return FuncCache<T>.Instence();
    //    }
    //    public bool IsRegistered<T>() where T : class
    //    {
    //        return FuncCache<T>.Instence != null;
    //    }

    //    static class ObjectInitInfoCache<T>
    //    {
    //        public static ObjectInitInfo Instence;
    //    }

    //    static class FuncCache<T>
    //    {
    //        public static Func<T> Instence;
    //    }
    //    static class SingletonObjectCache<T>
    //    {
    //        public static T Instence;
    //    }
    //}

    public class Container : IContainer
    {
        ICache<Type, Func<object>> FuncCache = new SimpleCache<Type, Func<object>>(MemberInfoComparer<Type>.Default);
        ICache<Type, object> SingletonObjectCache = new SimpleCache<Type, object>(MemberInfoComparer<Type>.Default);

        public virtual void Register<T>(Func<T> func) where T : class
        {
            Register<T>(func, false);
        }
        public virtual void Register<T>(Func<T> func, bool isSingleton) where T : class
        {
            if (isSingleton)
            {
                SingletonObjectCache.InvalidateItem(typeof(T));
                SingletonObjectCache.FetchOrCreateItem(typeof(T), p => func());
            }
            FuncCache.InvalidateItem(typeof(T));
            FuncCache.FetchOrCreateItem(typeof(T), p => func);
        }

        public virtual T Resolve<T>() where T : class
        {
            var obj = SingletonObjectCache.FetchOrCreateItem(typeof(T), null);
            if (obj != null) return (T)obj;
            var func = FuncCache.FetchOrCreateItem(typeof(T), null);
            if (func == null)
            {
                throw new BasicLibException("该对象尚未注册过.");
            }
            return (T)func();
        }
        public bool IsRegistered<T>() where T : class
        {
            return FuncCache.FetchOrCreateItem(typeof(T), null) != null;
        }
    }

}